package com.mspbots.core.wise.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mspbots.core.AbstractBaseServiceImpl;
import com.mspbots.core.teams.mapper.TeamsUserMapper;
import com.mspbots.core.teams.model.TeamsUser;
import com.mspbots.core.wise.controller.params.UserMappingParams;
import com.mspbots.core.wise.mapper.*;
import com.mspbots.core.wise.model.Tenant;
import com.mspbots.core.wise.model.TenantUser;
import com.mspbots.core.wise.model.TenantUserMapping;
import com.mspbots.core.wise.model.Users;
import com.mspbots.core.wise.model.dto.UserMappingCommand;
import com.mspbots.core.wise.model.dto.UserMappingDetail;
import com.mspbots.core.wise.model.dto.UserMappingResponse;
import com.mspbots.core.wise.service.TenantUserMappingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * com.mspbots.core.service.impl.TenantUsersMappingServiceImpl
 *
 * @author Jun Zhou
 * @date 15:14 2019/7/29
 **/
@Slf4j
@Service
public class TenantUsersMappingServiceImpl extends AbstractBaseServiceImpl<TenantUsersMappingMapper, TenantUserMapping>
        implements TenantUserMappingService {
    @Autowired
    private TenantUserConfigurationMapper tenantUserConfigurationMapper;
    @Autowired
    private TenantConfigurationMapper tenantConfigurationMapper;
    @Autowired
    private TenantUserMapper tenantUserMapper;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private TeamsUserMapper teamsUserMapper;


    @Override
    public UserMappingResponse findByOne(UserMappingParams params) {
        QueryWrapper<TenantUserMapping> queryWrapper = Wrappers.query();
        queryWrapper.eq(!StringUtils.isEmpty(params.getId()), "mapping.id", params.getId());
        queryWrapper.eq(!StringUtils.isEmpty(params.getTenantId()), "mapping.tenant_id", params.getTenantId());
        queryWrapper.eq(!StringUtils.isEmpty(params.getTenantUserId()), "mapping.tenant_user_id", params.getTenantUserId());
        queryWrapper.eq(!StringUtils.isEmpty(params.getTeamsUserId()), "mapping.teams_user_id", params.getTeamsUserId());
        queryWrapper.eq(!StringUtils.isEmpty(params.getSheetUserId()), "mapping.sheet_user_id", params.getSheetUserId());
        UserMappingResponse userMappingResponse = this.baseMapper.findByOne(queryWrapper);
        log.info("userMappingResponse::{}", userMappingResponse);

        if (!ObjectUtils.isEmpty(userMappingResponse) && !ObjectUtils.isEmpty(userMappingResponse.getTeamsEmail())) {
            Users users = this.usersMapper.selectOne(Wrappers.<Users>lambdaQuery().eq(Users::getUsername, userMappingResponse.getTeamsEmail().toLowerCase()));
            log.info("findByOne:users:{}", users);
            if (!ObjectUtils.isEmpty(users) && !ObjectUtils.isEmpty(users.getTimezoneShort())) {
                userMappingResponse.setTz(users.getTimezoneOffset());
                userMappingResponse.setTzStr(users.getTimezoneShort());
            } else {
                if (!ObjectUtils.isEmpty(users) && !ObjectUtils.isEmpty(users.getTenantId())) {
                    Tenant tenant = tenantMapper.selectById(users.getTenantId());
                    if (!ObjectUtils.isEmpty(tenant) && !ObjectUtils.isEmpty(tenant.getTimezoneShort())) {
                        userMappingResponse.setTz(tenant.getTimezoneOffset());
                        userMappingResponse.setTzStr(tenant.getTimezoneShort());
                    } else {
                        userMappingResponse.setTz("+00:00");
                        userMappingResponse.setTzStr("UTC");
                    }
                } else {
                    userMappingResponse.setTz("+00:00");
                    userMappingResponse.setTzStr("UTC");
                }
            }
        }

        return userMappingResponse;
    }


    @Override
    public boolean existsByTenantAndUserId(Long tenantId, Long userId) {
        List<TenantUserMapping> teamsUsers = this.baseMapper.selectList(Wrappers.<TenantUserMapping>lambdaQuery()
                .eq(TenantUserMapping::getTenantId, tenantId)
                .eq(TenantUserMapping::getTenantUserId, userId)
        );
        return teamsUsers.size() > 0;
    }

    @Override
    public UserMappingDetail detail(UserMappingParams params) {
        UserMappingDetail userMappingDetail = this.baseMapper.detail(params);
        if (userMappingDetail != null) {
            String email = null;
            if (!StringUtils.isEmpty(userMappingDetail.getTeamsUserId())) {
                TeamsUser teamsUser = teamsUserMapper.selectOne(Wrappers.<TeamsUser>lambdaQuery().eq(TeamsUser::getTenantId, userMappingDetail.getTenantId()).eq(TeamsUser::getTeamsUserId, userMappingDetail.getTeamsUserId()));
                email = teamsUser != null ? teamsUser.getTeamsMail() : null;
            }

            if (StringUtils.isEmpty(email) && !ObjectUtils.isEmpty(userMappingDetail.getTenantUserId())) {
                TenantUser tenantUser = tenantUserMapper.selectById(userMappingDetail.getTenantUserId());
                email = tenantUser != null ? tenantUser.getEmail() : null;
            }
            if (!StringUtils.isEmpty(email)) {
                Users users = usersMapper.selectOne(Wrappers.<Users>lambdaQuery().eq(Users::getUsername, email.toLowerCase()));
                if (!ObjectUtils.isEmpty(users)) {
                    userMappingDetail.setTz(users.getTimezoneOffset());
                    userMappingDetail.setTzStr(users.getTimezoneShort());
                    userMappingDetail.setUserId(users.getId());
                }
            }

            Tenant tenant = tenantMapper.selectById(params.getTenantId());
            if (StringUtils.isEmpty(userMappingDetail.getTz())) {
                userMappingDetail.setTz(tenant.getTimezoneOffset());
            }
            if (StringUtils.isEmpty(userMappingDetail.getTzStr())) {
                userMappingDetail.setTzStr(tenant.getTimezoneShort());
            }
        }
        return userMappingDetail;
    }

    @Override
    public UserMappingCommand commandDetail(UserMappingParams params) {
        log.info("commandDetail teamsUserId::{}", params.getTeamsUserId());
        UserMappingCommand command = this.baseMapper.selectCommandDetail(params);

        if (ObjectUtils.isEmpty(command)) {
            log.info("commandDetail TenantUserConfig is null! :teamsUserId::{}", params.getTeamsUserId());
            return null;
        }
        if (ObjectUtils.isEmpty(command.getUsername())) {
            command.setUsername(command.getTeamsMail());
        }

        if (StringUtils.isEmpty(command.getTz()) || "UTC".equalsIgnoreCase(command.getTz())) {
            Tenant tenant = tenantMapper.selectById(command.getTenantId());
            log.info("commandDetail TenantConfig  :teamsUserId::{},tenant", params.getTeamsUserId(), tenant);
            command.setTz(tenant.getTimezoneShort());
            command.setOffset(tenant.getTimezoneOffset());
            if (StringUtils.isEmpty(tenant.getTimezoneShort())) {
                command.setTz("UTC");
                command.setOffset("+00:00");
            }
        }


        /*TenantUserMapping tum = this.getOne(Wrappers.<TenantUserMapping>lambdaQuery().eq(TenantUserMapping::getTeamsUserId,command.getTeamsUserId()).eq(TenantUserMapping::getTenantId,command.getTenantId()));
        if(!ObjectUtils.isEmpty(tum)){
            TenantUserTimezone tut =tenantUserConfigurationMapper.selectTenantUserTimezone(tum.getTenantUserId());
            if(!ObjectUtils.isEmpty(tut)){
                log.info("commandDetail user timezone  tut::{},{}",tut.getTimezone(),tut.getTimezoneOffset());
                command.setTz(tut.getTimezone());
                command.setOffset(tut.getTimezoneOffset());
            }
        }*/

        /*if (StringUtils.isEmpty(command.getTz()) || "UTC".equalsIgnoreCase(command.getTz())) {

            TenantConfiguration timezone = tenantConfigurationMapper.selectOne(Wrappers.<TenantConfiguration>lambdaQuery()
                    .eq(TenantConfiguration::getKeyword, "timezone")
                    .eq(TenantConfiguration::getTenantId,command.getTenantId()));
            if (!ObjectUtils.isEmpty(timezone)) {
                log.info("commandDetail tenant timezone::{}",timezone.getKeywordValue());
                command.setTz(timezone.getKeywordValue());
            }
            TenantConfiguration timezoneOffset = tenantConfigurationMapper.selectOne(Wrappers.<TenantConfiguration>lambdaQuery()
                    .eq(TenantConfiguration::getKeyword, "timezone_offset")
                    .eq(TenantConfiguration::getTenantId,command.getTenantId()));
            if (!ObjectUtils.isEmpty(timezoneOffset)) {
                log.info("commandDetail tenant Offset::{}",timezoneOffset.getKeywordValue());
                command.setOffset(timezoneOffset.getKeywordValue());
            }

        }*/

        /*UserMappingCommand tc = this.baseMapper.selectCommandDetailTenantConf(command.getTenantId());
        if(ObjectUtils.isEmpty(tc)){
            log.info("commandDetail TenantConfig is null! :teamsUserId::{}",params.getTeamsUserId());
        }
        String str = tc.getTenantTz();
        if(str.contains("(") && str.length() > 10){
            str = str.split("\\(")[0].trim();
        }
        command.setTz(str);
        command.setOffset(tc.getTenantOffset());*/
        return command;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(TenantUserMapping entity) {
        int result;
        if (this.existsByTenantAndUserId(entity.getTenantId(), entity.getTenantUserId())) {
            result = this.baseMapper.updateById(entity);
        } else {
            result = this.baseMapper.insert(entity);
        }
        return result > 0;
    }
}
